using CSharpX;
using System;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;

namespace UnityX
{
    //滑动开关按钮
    [ExecuteAlways]
    [DisallowMultipleComponent]
    [RequireComponent(typeof(CanvasRenderer))]
    [AddComponentMenu("UI/UnityX/OnOffSlider")]
    public class OnOffSlider : MaskableGraphic, IPointerClickHandler
    {
        public delegate void ValueChangedCallback(bool open);
        public event ValueChangedCallback onValueChanged;

        protected float m_T = 1;
        [SerializeField]
        protected bool m_OnOff = true;
        [SerializeField]
        protected Texture m_Texture;

        public bool Interactable = true;
        public Color OnColor = Color.white;
        public Color OffColor = Color.white;
        public Color OnBackgroundColor = Color.green;
        public Color OffBackgroundColor = Color.gray;
        public float AnimationSpeed = 4;
        public float SizeScale = 0.8f;

        public bool open
        {
            get
            {
                return m_OnOff;
            }
            set
            {
                if (m_OnOff != value)
                {
                    m_OnOff = value;
                    onValueChanged?.Invoke(value);
                    if (!isActiveAndEnabled)
                    {
                        if (value) m_T = 1;
                        else m_T = 0;
                        SetVerticesDirty();
                    }
                }
            }
        }
        public Texture texture
        {
            get
            {
                return m_Texture;
            }
            set
            {
                m_Texture = value;
                SetMaterialDirty();
            }
        }
        public override Texture mainTexture
        {
            get
            {
                if (m_Texture == null)
                {
                    if (material != null && material.mainTexture != null)
                    {
                        return material.mainTexture;
                    }
                    return s_WhiteTexture;
                }
                return m_Texture;
            }
        }
        protected void LateUpdate()
        {
            if (m_OnOff)
            {
                if (m_T < 1)
                {
                    m_T += Time.deltaTime * AnimationSpeed;
                    if (m_T > 1)
                    {
                        m_T = 1;
                    }
                    SetVerticesDirty();
                }
            }
            else
            {
                if (m_T > 0)
                {
                    m_T -= Time.deltaTime * AnimationSpeed;
                    if (m_T < 0)
                    {
                        m_T = 0;
                    }
                    SetVerticesDirty();
                }
            }
        }
        public void OnPointerClick(PointerEventData eventData)
        {
            if (!Interactable) return;
            m_OnOff = !m_OnOff;
            onValueChanged?.Invoke(m_OnOff);
        }
        protected override void OnPopulateMesh(VertexHelper vh)
        {
            vh.Clear();
            Rect rect = GetPixelAdjustedRect();

            Color32 color1 = Color.Lerp(OffBackgroundColor, OnBackgroundColor, Curve.L1(0, 1, 0, 0.5f, m_T));
            Color32 color2 = color1;
            Color32 color3 = Color.Lerp(OffBackgroundColor, OnBackgroundColor, Curve.L1(0, 1, 0.5f, 1, m_T));
            Color32 color4 = color3;
            float x = rect.x;
            float y = rect.y;
            float w = rect.width;
            float h = rect.height;
            vh.AddVert(new Vector3(x, y), color1, new Vector2(0, 0));
            vh.AddVert(new Vector3(x + (h / 2), y), color2, new Vector2(0.5f, 0));
            vh.AddVert(new Vector3(x + (w - (h / 2)), y), color3, new Vector2(0.5f, 0));
            vh.AddVert(new Vector3(x + w, y), color4, new Vector2(1, 0));
            vh.AddVert(new Vector3(x, y + h), color1, new Vector2(0, 1));
            vh.AddVert(new Vector3(x + (h / 2), y + h), color2, new Vector2(0.5f, 1));
            vh.AddVert(new Vector3(x + (w - (h / 2)), y + h), color3, new Vector2(0.5f, 1));
            vh.AddVert(new Vector3(x + w, y + h), color4, new Vector2(1, 1));
            vh.AddTriangle(0, 4, 5);
            vh.AddTriangle(0, 5, 1);
            vh.AddTriangle(1, 5, 6);
            vh.AddTriangle(1, 6, 2);
            vh.AddTriangle(2, 6, 7);
            vh.AddTriangle(2, 7, 3);

            Color32 color = Color.Lerp(OffColor, OnColor, m_T);
            float cx = (h / 2) + ((w - h) * m_T) + x;
            float cy = (h / 2) + y;
            float cr = (h / 2) * SizeScale;
            vh.AddVert(new Vector3(cx - cr, cy - cr), color, new Vector2(0, 0));
            vh.AddVert(new Vector3(cx - cr, cy + cr), color, new Vector2(0, 1));
            vh.AddVert(new Vector3(cx + cr, cy + cr), color, new Vector2(1, 1));
            vh.AddVert(new Vector3(cx + cr, cy - cr), color, new Vector2(1, 0));
            vh.AddTriangle(8, 9, 10);
            vh.AddTriangle(8, 10, 11);
        }
#if UNITY_EDITOR
        protected override void Reset()
        {
            if (m_Texture == null)
            {
                m_Texture = Resources.Load<Texture2D>("UnityX/Circle");
            }
            base.Reset();
        }
#endif
    }
}